<?php

use console\db\Migration;
use yii\base\InvalidConfigException;
use yii\rbac\DbManager;
use common\models\rbac\Route;
use yii\rbac\Item;
use mdm\admin\models\AuthItem;
use mdm\admin\models\BizRule;
use yii\helpers\Inflector;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;

/**
 * RBAC基础授权
 * 
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class m200104_091352_d_rbac extends Migration {

    /**
     * @throws yii\base\InvalidConfigException
     * @return DbManager
     */
    protected function getAuthManager() {
        $authManager = Yii::$app->getAuthManager();
        if (!$authManager instanceof DbManager) {
            throw new InvalidConfigException('You should configure "authManager" component to use database before executing this migration.');
        }
        return $authManager;
    }

    /**
     * @inheritdoc
     */
    public function safeUp() {
        $data = $this->getData('rbac.php');
        foreach ($data as $type => $items) {
            $method = 'save' . Inflector::camelize($type);
            $handler = array($this, $method);
            if ($this->hasMethod($method) && is_callable($handler)) {
                call_user_func_array($handler, [$items]);
            }
        }
    }

    /**
     * 保存路由
     * @param array $routes
     */
    protected function saveRoutes($routes) {
        if (empty($routes)) {
            return;
        }
        $model = new Route();
        $model->addNew($routes);
    }

    /**
     * 保存角色
     * @param array $roles
     */
    protected function saveRoles($roles) {
        if (empty($roles)) {
            return;
        }
        $this->saveItems($roles, Item::TYPE_ROLE);
    }

    /**
     * 保存权限
     * @param array $permissions
     */
    protected function savePermissions($permissions) {
        if (empty($permissions)) {
            return;
        }
        $this->saveItems($permissions, Item::TYPE_PERMISSION);
    }

    /**
     * 保存授权项
     * @param array $items
     */
    protected function saveItems($items, $type) {
        if (empty($items)) {
            return;
        }
        $authItem = new AuthItem(null);
        $authItem->type = $type;
        foreach ($items as $attributes) {
            $routes = ArrayHelper::remove($attributes, 'routes');
            $ruleName = ArrayHelper::remove($attributes, 'ruleName');
            $ruleData = ArrayHelper::remove($attributes, 'ruleData');
            $adminers = ArrayHelper::remove($attributes, 'adminers');
            $_authItem = clone $authItem;
            $_authItem->setAttributes($attributes);
            $_authItem->ruleName = $ruleName;
            $_authItem->data = $ruleData ? Json::encode($ruleData) : null;
            if (!$_authItem->save()) {
                return false;
            }
            //授权路由
            if (!empty($routes)) {
                $_authItem->addChildren($routes);
            }
            //授权管理员
            if ($type == Item::TYPE_ROLE && !empty($adminers)) {
                foreach ($adminers as $adminId) {
                    $this->getAuthManager()->assign($_authItem, $adminId);
                }
            }
        }
    }

    /**
     * 保存规则
     * @param array $rules
     */
    protected function saveRules($rules) {
        if (empty($rules)) {
            return;
        }
        $ruleModel = new BizRule(null);
        foreach ($rules as $attributes) {
            $_ruleModel = clone $ruleModel;
            $_ruleModel->setAttributes($attributes);
            $_ruleModel->save();
        }
    }

    /**
     * @inheritdoc
     */
    public function safeDown() {
        $this->getAuthManager()->removeAll();
        $this->getAuthManager()->removeAllRules();
    }

}
